package com.aliyun.gts.sso.util;

import com.alibaba.fastjson.JSON;
import io.jsonwebtoken.*;
import io.jsonwebtoken.impl.DefaultClaims;
import io.jsonwebtoken.impl.DefaultJwsHeader;
import io.jsonwebtoken.impl.TextCodec;
import io.jsonwebtoken.impl.crypto.DefaultJwtSigner;
import io.jsonwebtoken.impl.crypto.JwtSigner;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.crypto.spec.SecretKeySpec;

//import javax.servlet.http.Cookie;
import jakarta.servlet.http.Cookie;
import java.security.Key;
import java.util.Date;

@Slf4j
@Service
public class JwtTokenUtils {

    private static final String ISSUER = "sf.work";
    private static final String JWT_SIGN_KEY = "/PZcNHZbc3ZyYqoQDN23kax0N4718sO/Y7hdO3hFV3w";

    public static String generateJwtToken(String sub) {
        byte[] bytes = TextCodec.BASE64.decode(JWT_SIGN_KEY);
        Key key = new SecretKeySpec(bytes, SignatureAlgorithm.HS256.getJcaName());
        JwtSigner jwtSigner = new DefaultJwtSigner(SignatureAlgorithm.HS256, key);
        String headerPayload = generateJwtTokenHeaderBody(sub);
        String signedKey = jwtSigner.sign(headerPayload);
        return headerPayload + "." + signedKey;
    }

    public static Claims parseJwtTokenClaims(Cookie cookie) {
        if (cookie == null || StringUtils.isEmpty(cookie.getValue())) {
            return null;
        }
        try {
            //得到DefaultJwtParser
            return Jwts.parser()
                    //设置签名的秘钥
                    .setSigningKey(JWT_SIGN_KEY)
                    //设置需要解析的token
                    .parseClaimsJws(cookie.getValue()).getBody();
        } catch (Throwable e) {
            log.error("fail to parse jwt token claims", e);
        }
        return null;
    }

    public static Claims parseJwtTokenClaims(String token) {
        if ( StringUtils.isEmpty(token)) {
            return null;
        }
        try {
            //得到DefaultJwtParser
            return Jwts.parser()
                    //设置签名的秘钥
                    .setSigningKey(JWT_SIGN_KEY)
                    //设置需要解析的token
                    .parseClaimsJws(token).getBody();
        } catch (Throwable e) {
            log.error("fail to parse jwt token claims", e);
        }
        return null;
    }

    private static String generateJwtTokenHeaderBody(String sub) {
        Date now = new Date();
        Date expiration = new Date(System.currentTimeMillis() + 24 * 3600 * 1000);
        JwsHeader header = new DefaultJwsHeader();
        header.setAlgorithm(SignatureAlgorithm.HS256.getValue());
        String base64UrlEncodedHeader = base64UrlEncode(header);
        Claims claims = new DefaultClaims();
        claims.setIssuer(ISSUER);
        claims.setSubject(sub);
        claims.setIssuedAt(now);
        claims.setExpiration(expiration);
        String base64UrlEncodedBody = base64UrlEncode(claims);
        return base64UrlEncodedHeader + JwtParser.SEPARATOR_CHAR + base64UrlEncodedBody;
    }

    private static String base64UrlEncode(Object o) {
        return TextCodec.BASE64URL.encode(JSON.toJSONBytes(o));
    }
}